using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using SharpBrowser.Model;

namespace SharpBrowser.Managers {
	internal static class BookmarkManager {
		private static readonly object FileLock = new object();
		private static string BookmarksFilePath => Path.Combine(ConfigManager.AppDataPath, "bookmarks.json");

		private static List<Bookmark> _cache;

		public static List<Bookmark> GetAll() {
			EnsureLoaded();
			// return a copy to prevent external mutation
			return _cache.Select(Clone).ToList();
		}

		public static Bookmark Add(string title, string url) {
			EnsureLoaded();
			var now = DateTime.UtcNow;
			var bm = new Bookmark {
				Id = Guid.NewGuid().ToString("N"),
				Title = title ?? "",
				Url = url ?? "",
				CreatedAt = now,
				UpdatedAt = now
			};
			_cache.Add(bm);
			Save();
			return Clone(bm);
		}

		public static bool Update(string id, string title, string url) {
			EnsureLoaded();
			var bm = _cache.FirstOrDefault(x => x.Id == id);
			if (bm == null) return false;
			if (title != null) bm.Title = title;
			if (url != null) bm.Url = url;
			bm.UpdatedAt = DateTime.UtcNow;
			Save();
			return true;
		}

		public static bool Delete(string id) {
			EnsureLoaded();
			var bm = _cache.FirstOrDefault(x => x.Id == id);
			if (bm == null) return false;
			_cache.Remove(bm);
			Save();
			return true;
		}

		public static int Import(List<Bookmark> incoming, bool replace = false) {
			EnsureLoaded();
			if (incoming == null) return 0;
			if (replace) {
				_cache = incoming.Select(NormalizeImported).ToList();
			}
			else {
				foreach (var b in incoming) {
					var nb = NormalizeImported(b);
					_cache.Add(nb);
				}
			}
			Save();
			return incoming.Count;
		}

		public static List<Bookmark> Export() {
			EnsureLoaded();
			return GetAll();
		}

		private static Bookmark NormalizeImported(Bookmark bm) {
			var now = DateTime.UtcNow;
			return new Bookmark {
				Id = string.IsNullOrWhiteSpace(bm.Id) ? Guid.NewGuid().ToString("N") : bm.Id,
				Title = bm.Title ?? "",
				Url = bm.Url ?? "",
				CreatedAt = bm.CreatedAt == default ? now : bm.CreatedAt,
				UpdatedAt = bm.UpdatedAt == default ? now : bm.UpdatedAt
			};
		}

		private static void EnsureLoaded() {
			if (_cache != null) return;
			lock (FileLock) {
				if (_cache != null) return;
				if (!File.Exists(BookmarksFilePath)) {
					_cache = new List<Bookmark>();
					Save();
					return;
				}
				try {
					var json = File.ReadAllText(BookmarksFilePath);
					var list = JsonConvert.DeserializeObject<List<Bookmark>>(json);
					_cache = list ?? new List<Bookmark>();
				}
				catch {
					_cache = new List<Bookmark>();
				}
			}
		}

		private static void Save() {
			lock (FileLock) {
				var json = JsonConvert.SerializeObject(_cache, Formatting.Indented);
				File.WriteAllText(BookmarksFilePath, json);
			}
		}

		private static Bookmark Clone(Bookmark bm) {
			return new Bookmark {
				Id = bm.Id,
				Title = bm.Title,
				Url = bm.Url,
				CreatedAt = bm.CreatedAt,
				UpdatedAt = bm.UpdatedAt
			};
		}
	}
}


